1.DOM简介 文档对象模型 (Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML 或者XML)的标准编程接口 ,通过这些 DOM 接口可以改变网页的内容、结构和样式。
文档 :一个页面就是一个文档,DOM 中使用 document 表示
元素 :页面中的所有标签都是元素,DOM 中使用 element 表示
节点 :网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示
DOM 把以上内容都看做是对象
2.获取元素 (1)根据ID获取 1 2 3 4 var timer = document .getElementById('time' );console .dir(timer);
(2)根据标签名获取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 document .getElementsByTagName('标签名' );var lis = document .getElementsByTagName('li' );console .log(lis);console .log(lis[0 ]);for (var i = 0 ; i < lis.length; i++) { console .log(lis[i]); } var ol = document .getElementsByTagName('ol' ); console .log(ol[0 ].getElementsByTagName('li' ));var ol = document .getElementById('ol' );console .log(ol.getElementsByTagName('li' ));
(3)通过 HTML5 新增的方法获取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var boxs = document .getElementsByClassName('box' );console .log(boxs);var firstBox = document .querySelector('.box' );console .log(firstBox);var nav = document .querySelector('#nav' );console .log(nav);var li = document .querySelector('li' );console .log(li);var allBox = document .querySelectorAll('.box' );console .log(allBox);var lis = document .querySelectorAll('li' );console .log(lis);
(4)特殊元素获取 1 2 3 4 5 6 7 var bodyEle = document .body;console .log(bodyEle);console .dir(bodyEle);var htmlEle = document .documentElement;console .log(htmlEle);
3.事件基础 事件三要素 (事件源 事件类型 事件处理程序)
1 2 3 4 5 6 7 8 var btn = document .getElementById('btn' );btn.onclick = function ( ) { alert('点秋香' ); }
4.操作元素 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var btn = document .querySelector('button' );var div = document .querySelector('div' );btn.onclick = function ( ) { div.innerHTML = getDate(); } function getDate ( ) { var date = new Date (); var year = date.getFullYear(); var month = date.getMonth() + 1 ; var dates = date.getDate(); var arr = ['星期日' , '星期一' , '星期二' , '星期三' , '星期四' , '星期五' , '星期六' ]; var day = date.getDay(); return '今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]; } var p = document .querySelector('p' );p.innerHTML = getDate();
5.innerText 和 innerHTML 的区别 1 2 3 4 5 6 7 8 9 var div = document .querySelector('div' );div.innerHTML = '<strong>今天是:</strong> 2019' ; var p = document .querySelector('p' );console .log(p.innerText);console .log(p.innerHTML);
6.修改元素属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 var ldh = document .getElementById('ldh' );var zxy = document .getElementById('zxy' );var img = document .querySelector('img' );zxy.onclick = function ( ) { img.src = 'images/zxy.jpg' ; img.title = '张学友思密达' ; } ldh.onclick = function ( ) { img.src = 'images/ldh.jpg' ; img.title = '刘德华' ; }
7.表单属性设置 this 指向的是事件函数的调用者
1 2 3 4 5 6 7 8 9 10 11 12 13 var btn = document .querySelector('button' );var input = document .querySelector('input' );btn.onclick = function ( ) { input.value = '被点击了' ; this .disabled = true ; }
案例 :仿京东显示隐藏密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <body > <div class ="box" > <label for ="" > <img src ="images/close.png" alt ="" id ="eye" > </label > <input type ="password" name ="" id ="pwd" > </div > <script > var eye = document .getElementById('eye' ); var pwd = document .getElementById('pwd' ); var flag = 0 ; eye.onclick = function ( ) { if (flag == 0) { pwd.type = 'text' ; eye.src = 'images/open.png' ; flag = 1 ; } else { pwd.type = 'password' ; eye.src = 'images/close.png' ; flag = 0; } } </script > </body >
8.修改样式属性 (1)element.style 行内样式操作 1 2 3 4 5 6 7 8 var div = document .querySelector('div' );div.onclick = function ( ) { this .style.backgroundColor = 'purple' ; this .style.width = '250px' ; }
注意 :
JS 里面的样式采取驼峰命名法 比如 fontSize、 backgroundColor
JS 修改 style 样式操作,产生的是行内样式 ,CSS 权重比较高
案例 :关闭二维码案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <body > <div class ="box" > <label for ="" > <img src ="images/close.png" alt ="" id ="eye" > </label > <input type ="password" name ="" id ="pwd" > </div > <script > var eye = document .getElementById('eye' ); var pwd = document .getElementById('pwd' ); var flag = 0 ; eye.onclick = function ( ) { if (flag == 0) { pwd.type = 'text' ; eye.src = 'images/open.png' ; flag = 1 ; } else { pwd.type = 'password' ; eye.src = 'images/close.png' ; flag = 0; } } </script > </body >
(2)element.className 类名样式操作 1 2 3 4 5 6 7 8 9 10 11 12 13 <body > <div class ="first" > 文本</div > <script > var test = document .querySelector('div' ); test.onclick = function ( ) { this .className = 'first change' ; } </script > </body >
9.排他思想 如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:
所有元素全部清除样式(干掉其他人)
给当前元素设置样式 (留下我自己)
注意顺序不能颠倒,首先干掉其他人,再设置自己
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <body > <button > 按钮1</button > <button > 按钮2</button > <button > 按钮3</button > <button > 按钮4</button > <button > 按钮5</button > <script > var btns = document .getElementsByTagName('button' ); for (var i = 0 ; i < btns.length; i++) { btns[i].onclick = function ( ) { for (var i = 0 ; i < btns.length; i++) { btns[i].style.backgroundColor = '' ; } this .style.backgroundColor = 'pink' ; } } </script > </body >
案例 :全选反选案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <script > var j_cbAll = document .getElementById('j_cbAll' ); var j_tbs = document .getElementById('j_tb' ).getElementsByTagName('input' ); j_cbAll.onclick = function ( ) { console .log(this .checked); for (var i = 0 ; i < j_tbs.length; i++) { j_tbs[i].checked = this .checked; } } for (var i = 0 ; i < j_tbs.length; i++) { j_tbs[i].onclick = function ( ) { var flag = true ; for (var i = 0 ; i < j_tbs.length; i++) { if (!j_tbs[i].checked) { flag = false ; break ; } } j_cbAll.checked = flag; } } </script >
10.自定义属性的操作 (1)获取属性值
element.属性 获取内置属性值(元素本身自带的属性)
element.getAttribute(‘属性’); 主要获得自定义的属性 (标准) 程序员自定义的属性
(2)设置属性值
element.属性 设置内置属性值
element.setAttribute(‘属性’,’值’); 主要设置自定义的属性 (标准)
(3)移除属性
element.removeAttribute(‘属性’);
(4)H5新增自定义属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <body > <div getTime ="20" data-index ="2" data-list-name ="andy" > </div > <script > var div = document .querySelector('div' ); console .log(div.getAttribute('getTime' )); div.setAttribute('data-time' , 20 ); console .log(div.getAttribute('data-index' )); console .log(div.getAttribute('data-list-name' )); console .log(div.dataset); console .log(div.dataset.index); console .log(div.dataset['index' ]); console .log(div.dataset.listName); console .log(div.dataset['listName' ]); </script > </body >
案例 :Tab栏切换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 <body > <div class ="tab" > <div class ="tab_list" > <ul > <li class ="current" > 商品介绍</li > <li > 规格与包装</li > <li > 售后保障</li > <li > 商品评价(50000)</li > <li > 手机社区</li > </ul > </div > <div class ="tab_con" > <div class ="item" style ="display: block;" > 商品介绍模块内容 </div > <div class ="item" > 规格与包装模块内容 </div > <div class ="item" > 售后保障模块内容 </div > <div class ="item" > 商品评价(50000)模块内容 </div > <div class ="item" > 手机社区模块内容 </div > </div > </div > <script > var tab_list = document .querySelector('.tab_list' ); var lis = tab_list.querySelectorAll('li' ); var items = document .querySelectorAll('.item' ); for (var i = 0 ; i < lis.length; i++) { lis[i].setAttribute('index' , i); lis[i].onclick = function ( ) { for (var i = 0 ; i < lis.length; i++) { lis[i].className = '' ; } this .className = 'current' ; var index = this .getAttribute('index' ); console .log(index); for (var i = 0 ; i < items.length; i++) { items[i].style.display = 'none' ; } items[index].style.display = 'block' ; } } </script > </body >
11.节点操作 (1)父节点操作 1 2 3 4 var erweima = document .querySelector('.erweima' );console .log(erweima.parentNode);
(2)子节点操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var ul = document .querySelector('ul' );var lis = ul.querySelectorAll('li' );console .log(ul.childNodes);console .log(ul.childNodes[0 ].nodeType);console .log(ul.childNodes[1 ].nodeType);console .log(ul.children);var ol = document .querySelector('ol' );console .log(ol.firstChild);console .log(ol.lastChild);console .log(ol.firstElementChild);console .log(ol.lastElementChild);console .log(ol.children[0 ]);console .log(ol.children[ol.children.length - 1 ]);
案例 :新浪下拉菜单
1 2 3 4 5 6 7 8 9 10 11 12 var nav = document .querySelector('.nav' );var lis = nav.children; for (var i = 0 ; i < lis.length; i++) { lis[i].onmouseover = function ( ) { this .children[1 ].style.display = 'block' ; } lis[i].onmouseout = function ( ) { this .children[1 ].style.display = 'none' ; } }
(3)兄弟节点 1 2 3 4 5 6 7 var div = document .querySelector('div' );console .log(div.nextSibling);console .log(div.previousSibling);console .log(div.nextElementSibling);console .log(div.previousElementSibling);
(4)创建和添加节点 1 2 3 4 5 6 7 8 9 var li = document .createElement('li' );var ul = document .querySelector('ul' );ul.appendChild(li); var lili = document .createElement('li' );ul.insertBefore(lili, ul.children[0 ]);
(5)删除节点 1 2 3 4 5 6 7 8 9 10 11 12 13 var ul = document .querySelector('ul' );var btn = document .querySelector('button' );btn.onclick = function ( ) { if (ul.children.length == 0 ) { this .disabled = true ; } else { ul.removeChild(ul.children[0 ]); } }
案例 :简单留言板(新增/删除留言)
阻止链接跳转需要添加 javascript:void(0); 或者 javascript:;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <body > <textarea name ="" id ="" > </textarea > <button > 发布</button > <ul > </ul > <script > var btn = document .querySelector('button' ); var text = document .querySelector('textarea' ); var ul = document .querySelector('ul' ); btn.onclick = function ( ) { if (text.value == '' ) { alert('您没有输入内容' ); return false ; } else { var li = document .createElement('li' ); li.innerHTML = text.value + "<a href ='javascript:;' > 删除</a > "; ul.insertBefore(li, ul.children[0]); var as = document .querySelectorAll('a' ); for (var i = 0 ; i < as .length; i++) { as [i].onclick = function ( ) { ul.removeChild(this .parentNode); } } } } </script > </body >
(6)克隆节点 1 2 3 4 5 var ul = document .querySelector('ul' );var lili = ul.children[0 ].cloneNode(true );ul.appendChild(lili);
案例 :动态生成表格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <meta http-equiv ="X-UA-Compatible" content ="ie=edge" > <title > Document</title > <style > table { width: 500px; margin: 100px auto; border-collapse: collapse; text-align: center; } td, th { border : 1px solid #333 ; } thead tr { height: 40px; background-color : #ccc ; } </style > </head > <body > <table cellspacing ="0" > <thead > <tr > <th > 姓名</th > <th > 科目</th > <th > 成绩</th > <th > 操作</th > </tr > </thead > <tbody > </tbody > </table > <script > var datas = [{ name: '魏璎珞' , subject: 'JavaScript' , score: 100 }, { name: '弘历' , subject: 'JavaScript' , score: 98 }, { name: '傅恒' , subject: 'JavaScript' , score: 99 }, { name: '明玉' , subject: 'JavaScript' , score: 88 }, { name: '大猪蹄子' , subject: 'JavaScript' , score: 0 }]; var tbody = document .querySelector('tbody' ); for (var i = 0 ; i < datas.length; i++) { var tr = document .createElement('tr' ); tbody.appendChild(tr); for (var k in datas[i]) { var td = document .createElement('td' ); td.innerHTML = datas[i][k]; tr.appendChild(td); } var td = document .createElement('td' ); td.innerHTML = '<a href ="javascript:;" > 删除 </a > '; tr.appendChild(td); } var as = document .querySelectorAll('a' ); for (var i = 0 ; i < as .length; i++) { as [i].onclick = function ( ) { tbody.removeChild(this .parentNode.parentNode) } } </script > </body > </html >
12.三种方式创建元素的区别(面试考点) document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
1 document .write('<div>123</div>' );
innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
1 2 3 4 var inner = document .querySelector('.inner' );for (var i = 0 ; i <= 100 ; i++) { inner.innerHTML += '<a href="#">百度</a>' }
innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
1 2 3 4 5 var arr = [];for (var i = 0 ; i <= 100 ; i++) { arr.push('<a href="#">百度</a>' ); } inner.innerHTML = arr.join('' );
createElement() 创建多个元素效率稍低一点点,但是结构更清晰
1 2 3 4 5 var create = document .querySelector('.create' );for (var i = 0 ; i <= 100 ; i++) { var a = document .createElement('a' ); create.appendChild(a); }
总结 :不同浏览器下,innerHTML 效率要比 creatElement 高